OK, 我们继续,这次来聊聊类。

内有 Jon Snow大战异鬼, ?

熟悉后端的朋友们对类肯定都不陌生,如下面一段PHP的代码:

class Human
{

  protected $name;

  public function __construct($name)
  {
    $this->name = $name;
  }

  public function introduce()
  {
    echo '你好,我叫 ' . $this->name . PHP_EOL;
  }

}
$jack = new Human('Jack');
$jack->introduce();

上面的代码,我们创建了一个叫Human的类,初始化的时候传入名字,还有一个自我介绍的方法。

同样的功能到了JS的世界呢? 且看下面的代码(ES5):

var Human = function(name) {
  this.name = name;
};

Human.prototype.introduce = function() {
  console.log('你好,我叫 ' + this.name);
};

var jack = new Human('Jack');
jack.introduce();

对了,你没有看错,在JS的世界中,我们就是这么来实现类的开发的, 总感觉哪里不舒服对吧?

到了ES2015(ES6), 事情就变得美好了,一起来看看下面的代码:

class Human {

  constructor(name) {
    this.name = name;
  }

  introduce() {
    console.log(`你好,我是 ${this.name}`);
  }

}

let jack = new Human('Jack');
jack.introduce();

终于变得正常一些了,泪奔。。。

大家请记住,这只是语法糖,在这背后的实现依然是我们ES5中展示的代码,但是,我们用着爽就好,哈哈哈!!!

有了class关键字,理所当然就有extends喽,马上试试:

class Man extends Human {

  construtor(name) {
    super(name);
    this.gender = 'male';
  }

}

new Man('Jon').introduce();

继续泪奔,写法上不用为了实现继承,各种操作prototype了。

这里还要特殊讲一下静态方法:

class Tree {

  static new() {
    return new Tree();
  }

}

let tree1 = new Tree(); // Tree Object
let tree2 = Tree.new(); // Tree Object
tree1.new(); // TypeError: tree1.new is not a function

可以看到,静态方法只能在类中调用,而不能被类实例调用。

为了更好的体验JS面向对象开发,下面我们来实战一下,来写一个简单的自动MUD游戏,故事的场景是Jon Snow大战异鬼,?。

  • 主角Jon Snow将大战若干回合的异鬼,并最终和Night King决战!

  • Jon Snow每打败一个异鬼将吞噬该异鬼的等级到自己身上

  • Jon Snow有必杀攻击

分析一下:

  • 不管是Jon Snow, 异鬼和Night King, 对于游戏来说都是角色,所以我们应该有个角色基类。

    • 有名称,等级,血量等基础属性

    • 有攻击,升级,承受伤害等方法

  • Jon Snow 应该继承 角色基类,并拥有必杀攻击的方法

  • 需要有个游戏世界, 有场景,并可以控制游戏开始。

OK,编写代码:

class Role { //角色基类

  constructor(name, level = 1, health = 100) {
      this.name = name;
      this.level = level;
      this.health = health;
  }

  isDead() { //判断角色是否死亡
    return this.health <= 0;
  }

  levelUp(level = 1) { //升级
    this.level += level;
  }

  damage(power) { //受到伤害
    this.health = this.health - power;
  }

  attack(role) { //攻击
    this.strike(role);
  }

  strike(role) { //普通攻击
    let power = parseInt(Math.random() * 20 * this.level / 10);
    role.damage(power);
    console.log(`[${this.name}]攻击了[${role.name}], 造成了[${power}]点伤害`);
  }

}

class Hero extends Role {

    attack(role) { //攻击,有概率是用必杀攻击
        if (! this.isCriticalStrike()) {
            return this.criticalStrike(role);
        }

        return this.strike(role);
    }

    criticalStrike(role) { //必杀攻击
        let power = parseInt(200 * Math.random() + 50);
        role.damage(power);
        console.log(`[${this.name}]使用必杀攻击了[${role.name}], 造成了[${power}]点伤害`);
    }

    isCriticalStrike() {
        return Math.random() > 0.70;
    }

}

class Monster extends Role {

}

class Game { //游戏世界

  constructor() {
    this.name = "权利的游戏";
    this.hero = new Hero('Jon Snow', 10); // 初始化英雄Jon Snow
    this.monsters = [ //怪物集合,模拟简单的游戏关卡。
      new Monster('异鬼 01', 1, 10),
      new Monster('异鬼 02', 3, 30),
      new Monster('异鬼 03', 5, 50),
      new Monster('异鬼 04', 10, 100),
      new Monster('异鬼 05', 15, 150),
      new Monster('异鬼 06', 20, 200),
      new Monster('Night King', 50, 500)
    ];
    this.level = 0; // 游戏当前关卡记录
    console.log(`你在[${this.name}]中扮演[${this.hero.name}], 征程即将开始...`);
  }

  play() { // 游戏开始
    while (this.level < this.monsters.length && ! this.hero.isDead()) {
      let monster = this.monsters[this.level];
      console.log(`关卡[${this.level + 1}] 你遇到了[${monster.name}], 进入战斗:`);
      let offensive = this.hero;
      let defensive = monster;
      while (! this.hero.isDead() && ! monster.isDead()) {
        offensive.attack(defensive);
        let middleman = offensive;
        offensive = defensive;
        defensive = middleman;
      }
      if (this.hero.isDead()) {
        console.log(`你被[${monster.name}]打败了, 游戏结束!`);
        break;
      }
      if (monster.isDead()) {
        console.log(`你打败了[${monster.name}] 等级提升:[${monster.level}]`);
        this.hero.levelUp(monster.level);
        this.level ++;
      }
    }
    if (this.level === this.monsters.length) {
        console.log(`恭喜你通关游戏!`);
    }
  }

}

let game = new Game();
game.play();

执行一下,可以得到:

你在[权利的游戏]中扮演[Jon Snow], 征程即将开始...
关卡[1] 你遇到了[异鬼 01], 进入战斗:
[Jon Snow]使用必杀攻击了[异鬼 01], 造成了[114]点伤害
你打败了[异鬼 01] 等级提升:[1]
关卡[2] 你遇到了[异鬼 02], 进入战斗:
[Jon Snow]使用必杀攻击了[异鬼 02], 造成了[140]点伤害
你打败了[异鬼 02] 等级提升:[3]
关卡[3] 你遇到了[异鬼 03], 进入战斗:
[Jon Snow]使用必杀攻击了[异鬼 03], 造成了[69]点伤害
你打败了[异鬼 03] 等级提升:[5]
关卡[4] 你遇到了[异鬼 04], 进入战斗:
[Jon Snow]使用必杀攻击了[异鬼 04], 造成了[169]点伤害
你打败了[异鬼 04] 等级提升:[10]
关卡[5] 你遇到了[异鬼 05], 进入战斗:
[Jon Snow]攻击了[异鬼 05], 造成了[41]点伤害
[异鬼 05]攻击了[Jon Snow], 造成了[19]点伤害
[Jon Snow]攻击了[异鬼 05], 造成了[21]点伤害
[异鬼 05]攻击了[Jon Snow], 造成了[3]点伤害
[Jon Snow]使用必杀攻击了[异鬼 05], 造成了[223]点伤害
你打败了[异鬼 05] 等级提升:[15]
关卡[6] 你遇到了[异鬼 06], 进入战斗:
[Jon Snow]使用必杀攻击了[异鬼 06], 造成了[77]点伤害
[异鬼 06]攻击了[Jon Snow], 造成了[23]点伤害
[Jon Snow]使用必杀攻击了[异鬼 06], 造成了[221]点伤害
你打败了[异鬼 06] 等级提升:[20]
关卡[7] 你遇到了[Night King], 进入战斗:
[Jon Snow]使用必杀攻击了[Night King], 造成了[155]点伤害
[Night King]攻击了[Jon Snow], 造成了[88]点伤害
你被[Night King]打败了, 游戏结束!

大家可以调调参数,虐一虐大Boss吧,哈哈哈~~~~


chekun
3.4k 声望66 粉丝

Go Go Go!!!